package com.woniuxy.third.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniuxy.third.annotations.RequirePermission;
import com.woniuxy.third.enums.TokenEnum;
import com.woniuxy.third.enums.ResponseEnum;
import com.woniuxy.third.enyity.Perms;
import com.woniuxy.third.enyity.Role;
import com.woniuxy.third.enyity.User;
import com.woniuxy.third.result.ResponseResult;
import com.woniuxy.third.service.UserService;
import com.woniuxy.third.utils.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
@Component  //加入ioc容器
public class PermissionInterceptor extends HandlerInterceptorAdapter {

    @Resource
    private UserService userService;
    //日志
    private static final Logger logger = LoggerFactory.getLogger(PermissionInterceptor.class);
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        ResponseResult<Object> responseResult = new ResponseResult<>();
        //设置响应头
        response.setContentType("application/json;charset=utf-8");

        logger.debug("拦截请求");
        //得到token-得到账号
        String token = request.getHeader("authorization");

        //1.得到即将被访问的方法
        //如果是请求的handler中的方法
        if (handler instanceof HandlerMethod){
            //判断token是否为null
            if (token == null){
                logger.debug("没有登录");
                responseResult.setCode(500);
                responseResult.setMessage("你还没有登录");
                responseResult.setStatus(ResponseEnum.NO_LOGIN);
                String json = new ObjectMapper().writeValueAsString(responseResult);
                //返回数据
                response.getWriter().write(json);

                return false;
            }
            //校验token：有可能伪造、过期
            if (JwtUtil.verify(token) == TokenEnum.TOKEN_FAIL){
                logger.debug("token非法");

                responseResult.setCode(500);
                responseResult.setMessage("小样");
                String json = new ObjectMapper().writeValueAsString(responseResult);
                //返回数据
                response.getWriter().write(json);

                return false;
            }
            //判断是否过期
            if (JwtUtil.verify(token) == TokenEnum.TOKEN_EXPIRE){
                logger.debug("token过期，重新生成token");
                //重新生成token
                token = JwtUtil.generateToken(JwtUtil.getAccount(token));
                //更新前台的token
                //将token放到响应头
                logger.debug("将token设置到响应头，返回给前端");
                response.setHeader("authorization",token);
                //将该响应头暴露给第三方
                response.setHeader("Access-Control-Expose-Headers","authorization");
            }

            logger.debug("获取被请求的方法");
            HandlerMethod handlerMethod = (HandlerMethod)handler;
            //
            Method method = handlerMethod.getMethod();
            logger.debug("判断方法上是否有指定的注解");
            if (method.isAnnotationPresent(RequirePermission.class)){
                logger.debug("方法上有注解,得到注解对象");
                RequirePermission rp = method.getDeclaredAnnotation(RequirePermission.class);
                logger.debug("获取注解中的值");
                String perms = rp.value();
                logger.debug("value = " + perms);

                String account = JwtUtil.getAccount(token);
                //调用service通过用户名到数据库查询权限
                User user = userService.findByAccount(account);
                //遍历用户权限
                for(Role role:user.getRoles()){
                    for(Perms p : role.getPerms()){
                        if(p.getPname().equals(perms)){
                            logger.debug("有权限");
                            return true;
                        }
                    }
                }
                logger.debug("没有权限");
                responseResult = new ResponseResult<>(500,"你没有权限，请联系管理员",null);
                String json = new ObjectMapper().writeValueAsString(responseResult);
                response.getWriter().write(json);
                return false;
            }
        }

        return super.preHandle(request, response, handler);
    }
}
